/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：
* CreateTime：2020-05-25 14:05:29
* Version：1.0
* Modify Recorder：
*************************************************/

using System;
using UnityEngine;
using UnityEngine.Events;

namespace TinyToolKit
{
    [Serializable]
    public class Raycast2DEvent : UnityEvent<RaycastHit2D> { }
    
    public class MouseRaycast2D : MonoBehaviour
    {
        public Camera mainCam;
        public UpdateEvent updateEvent = UpdateEvent.LateUpdate;
        public LayerMask layerMask = -1;
        public float rayLength = -1;
        public Raycast2DEvent onEnter;
        public Raycast2DEvent onHover; 
        public Raycast2DEvent onExit;

        private void Start()
        {
            if (mainCam == null)
                mainCam = Camera.main;
        }

        private void Update()
        {
            ExecuteRaycast2D(UpdateEvent.Update);
        }
        
        private void LateUpdate()
        {
            ExecuteRaycast2D(UpdateEvent.LateUpdate);
        }

        RaycastHit2D newHitInfo;
        RaycastHit2D oldHitInfo; 
        
        private void ExecuteRaycast2D(UpdateEvent curEvent)
        {
            if (curEvent != updateEvent || mainCam == null) return;

            Vector2 origin = mainCam.ScreenToWorldPoint(Input.mousePosition);
            newHitInfo = Physics2D.Raycast(origin,Vector2.zero, rayLength >= 0 ? rayLength : Mathf.Infinity, layerMask.value);
            if (newHitInfo.collider != null)
            {
                if (newHitInfo.collider != oldHitInfo.collider)
                {
                    onEnter?.Invoke(newHitInfo);
                    if(oldHitInfo.collider)
                        onExit?.Invoke(oldHitInfo);
                    
                    oldHitInfo = newHitInfo;
                }
                else
                {
                    onHover?.Invoke(newHitInfo); 
                }
            }
            else if(oldHitInfo.collider)
            {
                onExit?.Invoke(oldHitInfo);
                oldHitInfo = new RaycastHit2D();
            }
        }
    }
}

